import { useMessage } from '@/hooks'
import { addStyleToHead } from '@/utils/style'
import { isObject, isFunction } from 'lodash-es'
import { getComAttrValue } from '../../utils/attrs'
import { getInsBwUtils } from '../../utils/setupLogic'
import { getNodeComSlots } from '@bitwit/base-com-render'
import {
  ref,
  unref,
  computed,
  watch,
  markRaw,
  onMounted,
  nextTick,
  shallowRef,
} from 'vue'
import { useComDesignStoreWithOut, getCustomComDesignInfo } from '@/store'

import type { BwVueIns } from '../../utils/model'
import {
  createInsCom,
  BwComTypeEnum,
  BwAntComNameEnum,
  BwVanComNameEnum,
  BwVxeComNameEnum,
  BwCustomComSoltTypeEnum,
  type BwGetCustomComInfoFun,
  type BwCustomComStructModel,
  type BwCustomComNodeAttrModel,
  type BwCustomComSlotInfoModel,
  type BwCustomComDesignInfoModel,
  type BwCustomComNodeEnableSlotInfoModel,
  type BwCustomComConventionSlotInfoModel,
} from '@bitwit/base-com-render'

import BwVueEle from './coms/vue/index.vue'

export function useDesignEle(props) {
  const designStore = useComDesignStoreWithOut()
  const { createWarningModal } = useMessage()

  const curNode = ref()
  const curEle = shallowRef<any>(null)
  const isModalDesign = ref<boolean>(false)
  const curComSlotList = ref<Array<BwCustomComConventionSlotInfoModel>>([])

  /** 是否需要特殊处理插槽 */
  const isSpecial = ref<boolean>(false)

  /** 当前组件名称 */
  const curComName = ref('')

  const extendBwUtils = computed(() => {
    const utils = getInsBwUtils({ params: {} })
    return utils
  })
  const curComProps = computed(() => {
    const nodeInfo: BwCustomComStructModel = props.nodeInfo
    const curAttrs = getComAttrs(nodeInfo.attrs)

    const classList: Array<string> = ['bw-design-drag-item']
    if (curAttrs.class) {
      classList.push(curAttrs.class)
    }

    if (nodeInfo.comName === BwAntComNameEnum.ACol) {
      classList.push('bw-col-item')
    }

    return {
      ...curAttrs,
      readonly: true,
      nodeId: nodeInfo.nodeId,
      comName: nodeInfo.comName,
      id: `com_${nodeInfo.nodeId}`,
      class: classList,
    }
  })

  const onEvents = {
    click(ev: Record<string, any>) {
      const nodeInfo = props.nodeInfo
      if (nodeInfo) {
        ev.stopPropagation()
        const nodeId = nodeInfo.nodeId ?? ''
        designStore.onSeleteNodeInfo(nodeId)
      }
    },

    mouseout(ev: Record<string, any>) {
      ev.stopPropagation()
      const nodeInfo = props.nodeInfo
      if (nodeInfo) {
        const nodeId = nodeInfo.nodeId ?? ''
        const ele = document.getElementById(`com_${nodeId}`)
        if (ele) {
          ele.classList.remove('bw-design-node-hover')
        }
      }
    },

    mouseover(ev: Record<string, any>) {
      ev.stopPropagation()
      const nodeInfo = props.nodeInfo
      if (nodeInfo) {
        const nodeId = nodeInfo.nodeId ?? ''
        const ele = document.getElementById(`com_${nodeId}`)

        if (ele) {
          ele.classList.add('bw-design-node-hover')
        }
      }
    },
  }

  /** 获取组件属性 */
  const getComAttrs = (
    data: Nullable<Record<string, BwCustomComNodeAttrModel>>
  ) => {
    const curAttrs: Record<string, any> = {}
    if (isObject(data)) {
      const vueIns: BwVueIns = props.vueIns
      const scopeData: Record<string, any> = props.scopeData
      Object.keys(data).forEach((key) => {
        const value = getComAttrValue(vueIns, data[key], scopeData)
        curAttrs[key] = value
      })
    }
    return curAttrs
  }

  /** 初始化组件插槽 */
  const initComSlotList = (
    slot: Array<BwCustomComSlotInfoModel>,
    enableList: Array<BwCustomComNodeEnableSlotInfoModel>,
    trendsSlotList: Array<BwCustomComConventionSlotInfoModel>
  ) => {
    const list: BwCustomComConventionSlotInfoModel[] = []
    if (Array.isArray(slot) && slot.length) {
      slot.forEach((item: BwCustomComSlotInfoModel) => {
        const slotType = item.slotType
        switch (slotType) {
          case BwCustomComSoltTypeEnum.convention: {
            const slotCInfo = item.conventionSlotInfo
            const curSlotInfo = enableList.find((n) => {
              const code = n.conventionSlotInfo?.slotCode
              return slotCInfo?.slotCode === code && code
            })

            if (curSlotInfo?.visible) {
              list.push({
                slotName: slotCInfo?.slotName ?? '',
                slotCode: slotCInfo?.slotCode ?? '',
                slotParams: slotCInfo?.slotParams,
              })
            }
            break
          }
          case BwCustomComSoltTypeEnum.trends: {
            const slotTInfo = item.trendsSlotInfo
            const curSlotInfo = enableList.find((n) => {
              const code = n.trendsSlotInfo?.logicCode
              return slotTInfo?.logicCode === code && code
            })
            if (curSlotInfo?.visible) {
              trendsSlotList.forEach((n) => {
                list.push({
                  slotName: n?.slotName ?? '',
                  slotCode: n?.slotName ?? '',
                  slotParams: n?.slotParams,
                })
              })
            }
          }
        }
      })
    }
    curComSlotList.value = list
  }

  /** 获取动态插槽变量 */
  // const getTrendSlotVar = (data?: BwCustomComTrendsSlotInfoModel) => {
  //   const vueIns: BwVueIns = props.vueIns

  //   console.log('获取动态插槽变量', vueIns, data)
  //   switch (data?.trendVarFrom) {
  //     case BwCustomComTrendSlotVarFromTypeEnum.comVar: {
  //       const fields = (data?.comVarName ?? '').split('.')
  //       return getObjectKeyValue(vueIns, fields, undefined)
  //     }
  //     case BwCustomComTrendSlotVarFromTypeEnum.comProps: {
  //       const curProps = vueIns.$props
  //       const fields = (data?.comPorpName ?? '').split('.')

  //       return getObjectKeyValue(curProps, fields, undefined)
  //     }
  //     default: {
  //       return undefined
  //     }
  //   }
  // }

  /** 挂载节点元素样式 */
  const mountComCss = (nodeId: string, css: Nullable<string>) => {
    if (css) {
      addStyleToHead(`curtom-com-${nodeId}`, css)
    }
  }

  onMounted(() => {
    const ele = unref(curNode)
    const curNodeEle = ele?.$el
    if (curNodeEle) {
      const nodeInfo: BwCustomComStructModel = props.nodeInfo
      curNodeEle?.setAttribute?.('nodeId', nodeInfo.nodeId)
    }
  })

  watch(
    () => props.nodeInfo,
    (newVal?: BwCustomComStructModel, oldVal?: BwCustomComStructModel) => {
      if (newVal && JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
        const nodeId = newVal.nodeId
        const comType = newVal.comType
        const comCode = newVal.comName ?? null
        const appCode = newVal.comAppCode ?? null
        const enableList = newVal.enableSlotList ?? []
        curComName.value = newVal.nodeName ?? ''

        mountComCss(nodeId, newVal.css)
        if (comType === BwComTypeEnum.custom) {
          if (appCode) {
            getCustomComDesignInfo(appCode, comCode).then((res) => {
              if (res) {
                createInsCom(
                  res as BwCustomComDesignInfoModel,
                  props.frontType,
                  getCustomComDesignInfo as BwGetCustomComInfoFun,
                  unref(extendBwUtils)
                ).then((insCom: any) => {
                  curEle.value = markRaw(insCom)

                  nextTick(() => {
                    const nodeEle = unref(curNode)
                    if (isFunction(nodeEle.bwSysGetComSlotInfoList)) {
                      const slotList = res.comSlots ?? []
                      const list = nodeEle.bwSysGetComSlotInfoList()
                      initComSlotList(slotList, enableList, list)
                    }
                  })
                })
              }
            })
          } else {
            createWarningModal({
              content: `没有找到自定义组件【${comCode}】，请检查！`,
            })
          }
        } else if (comType === BwComTypeEnum.vue) {
          curEle.value = markRaw(BwVueEle)
        } else {
          const slotList = getNodeComSlots(comCode)
          initComSlotList(slotList ?? [], enableList, [])
          switch (comCode) {
            case BwAntComNameEnum.AModal: {
              isModalDesign.value = true
              break
            }
            case BwVanComNameEnum.VanPopup: {
              isModalDesign.value = true
              break
            }

            /** 表格列 */
            case BwVxeComNameEnum.VxeColumn: {
              isSpecial.value = true
              break
            }
            /** 表格列分组 */
            case BwVxeComNameEnum.VxeColgroup: {
              isSpecial.value = true
              break
            }
            /** vant 选择器组 */
            case BwVanComNameEnum.VanPickerGroup: {
              isSpecial.value = true
              break
            }
            /** tooltip文字提示 */
            case BwAntComNameEnum.ATooltip: {
              isSpecial.value = true
              break
            }
            case BwAntComNameEnum.ATabs: {
              isSpecial.value = true
              break
            }
            case BwAntComNameEnum.ATabPane: {
              isSpecial.value = true
              break
            }

            default: {
              curEle.value = comCode
            }
          }
        }
      }
    },
    { deep: true, immediate: true }
  )
  return {
    curEle,
    curNode,
    onEvents,
    curComProps,
    curComSlotList,
    isModalDesign,
    isSpecial,
    curComName,
  }
}
